﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Web.Security;
namespace CaiGou.Common
{
    /// <summary>
    /// 提供一些常用加密方法的静态类
    /// </summary>
    public static class Encryption
    {
        private static string DesKey
        {
            get
            {
                return @"P@+#wG+Z";
            }
        }
        private static string DesIV
        {
            get
            {
                return @"L%n67}G/Mk@k%:~Y";
            }
        }
        private static string AesKey
        {
            get
            {
                return @")O[NB]6,YF}+efcaj{+oESb9d8>Z'e9M";
            }
        }
        private static string AesIV
        {
            get
            {
                return @"L+/~f4,Ir)b$=pkf";
            }
        }
        /// <summary>
        /// 对一串字符进行 MD5 加密，得到32字节的加密字符串
        /// </summary>
        /// <param name="keyword">所需要加密的字符串</param>
        /// <returns></returns>
        public static string MD5(string keyword)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(keyword, "MD5").ToLower();
        }
        /// <summary>
        /// 对一串字符进行 MD5 加密，得到16字节的加密字符串
        /// </summary>
        /// <param name="keyword">所需要加密的字符串</param>
        /// <returns></returns>
        public static string MD5_Short(string keyword)
        {
            string result = FormsAuthentication.HashPasswordForStoringInConfigFile(keyword, "MD5").ToLower();
            return result.Substring(8, 16);
        }
        /// <summary>
        /// 对一串字符进行 SHA1 加密
        /// </summary>
        /// <param name="keyword">所需要加密的字符串</param>
        /// <returns></returns>
        public static string SHA1(string keyword)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(keyword, System.Web.Configuration.FormsAuthPasswordFormat.SHA1.ToString()).ToLower();
        }
        public static string En_DEC(string keyword, string key, string IV)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider(); //把字符串放到byte数组中 
            byte[] inputByteArray = Encoding.Default.GetBytes(keyword);
            des.Key = Encoding.ASCII.GetBytes(key); //建立加密对象的密钥和偏移量 
            des.IV = Encoding.ASCII.GetBytes(IV); //原文使用ASCIIEncoding.ASCII方法的GetBytes方法 
            MemoryStream ms = new MemoryStream(); //使得输入密码必须输入英文文本 
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            ret.ToString();
            return ret.ToString();
        }
        /// <summary>
        /// 对一串字符进行 DES 加密
        /// </summary>
        /// <param name="keyword">所需要加密的字符串</param>
        /// <param name="mode">加密使用的模式</param>
        /// <param name="padding">加密使用的偏移方式</param>
        /// <returns></returns>
        public static string En_DES(string keyword, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
        {
            byte[] bKey = Encoding.UTF8.GetBytes(DesKey);
            byte[] bIV = Encoding.UTF8.GetBytes(DesIV);
            byte[] byteArray = Encoding.UTF8.GetBytes(keyword);
            string result = null;
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            des.Mode = mode;
            des.Padding = padding;
            try
            {
                using (MemoryStream mStream = new MemoryStream())
                {
                    using (CryptoStream cStream = new CryptoStream(mStream, des.CreateEncryptor(bKey, bIV), CryptoStreamMode.Write))
                    {
                        cStream.Write(byteArray, 0, byteArray.Length);
                        cStream.FlushFinalBlock();
                        result = Convert.ToBase64String(mStream.ToArray());
                    }
                }
            }
            catch
            {
            }
            des.Clear();
            des.Dispose();
            return result;
        }
        /// <summary>
        /// 对一串字符进行 DES 解密
        /// </summary>
        /// <param name="keyword">所需要解密的字符串</param>
        /// <param name="mode">解密使用的模式</param>
        /// <param name="padding">解密使用的偏移方式</param>
        /// <returns></returns>
        public static string De_DES(string keyword, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
        {
            byte[] bKey = Encoding.UTF8.GetBytes(DesKey);
            byte[] bIV = Encoding.UTF8.GetBytes(DesIV);
            byte[] byteArray = Convert.FromBase64String(keyword);
            string result = null;
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            des.Mode = mode;
            des.Padding = padding;
            try
            {
                using (MemoryStream mStream = new MemoryStream())
                {
                    using (CryptoStream cStream = new CryptoStream(mStream, des.CreateDecryptor(bKey, bIV), CryptoStreamMode.Write))
                    {
                        cStream.Write(byteArray, 0, byteArray.Length);
                        cStream.FlushFinalBlock();
                        result = Encoding.UTF8.GetString(mStream.ToArray());
                    }
                }
            }
            catch
            {
            }
            des.Clear();
            des.Dispose();
            return result;
        }
        /// <summary>
        /// 对一串字符进行 AES 加密
        /// </summary>
        /// <param name="keyword">所需要加密的字符串</param>
        /// <param name="mode">加密使用的模式</param>
        /// <param name="padding">加密使用的偏移方式</param>
        /// <returns></returns>
        public static string En_AES(string keyword, CipherMode mode = CipherMode.CFB, PaddingMode padding = PaddingMode.PKCS7)
        {
            byte[] bKey = Encoding.UTF8.GetBytes(DesKey);
            byte[] bIV = Encoding.UTF8.GetBytes(DesIV);
            byte[] byteArray = Encoding.UTF8.GetBytes(keyword);
            string result = null;
            Rijndael aes = Rijndael.Create();
            aes.Mode = mode;
            aes.Padding = padding;
            try
            {
                using (MemoryStream mStream = new MemoryStream())
                {
                    using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateEncryptor(bKey, bIV), CryptoStreamMode.Write))
                    {
                        cStream.Write(byteArray, 0, byteArray.Length);
                        cStream.FlushFinalBlock();
                        result = Convert.ToBase64String(mStream.ToArray());
                    }
                }
            }
            catch { }
            aes.Clear();
            aes.Dispose();
            return result;
        }
        /// <summary>
        /// 对一串字符进行 AES 解密
        /// </summary>
        /// <param name="keyword">所需要解密的字符串</param>
        /// <param name="mode">解密使用的模式</param>
        /// <param name="padding">解密使用的偏移方式</param>
        /// <returns></returns>
        public static string De_AES(string keyword, CipherMode mode = CipherMode.CFB, PaddingMode padding = PaddingMode.PKCS7)
        {
            byte[] bKey = Encoding.UTF8.GetBytes(DesKey);
            byte[] bIV = Encoding.UTF8.GetBytes(DesIV);
            byte[] byteArray = Convert.FromBase64String(keyword);
            string result = null;
            Rijndael aes = Rijndael.Create();
            aes.Mode = mode;
            aes.Padding = padding;
            try
            {
                using (MemoryStream mStream = new MemoryStream())
                {
                    using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateDecryptor(bKey, bIV), CryptoStreamMode.Write))
                    {
                        cStream.Write(byteArray, 0, byteArray.Length);
                        cStream.FlushFinalBlock();
                        result = Encoding.UTF8.GetString(mStream.ToArray());
                    }
                }
            }
            catch { }
            aes.Clear();
            return result;
        }
        public static string HMAC_SHA1(string str,string key,bool isBase64 = false)
        {
            byte[] bt = (new HMACSHA1(Encoding.UTF8.GetBytes(key))).ComputeHash(Encoding.UTF8.GetBytes(str));
            return isBase64 ? Convert.ToBase64String(bt) : Encoding.UTF8.GetString(bt);
        }
    }
}
